/**
 * Copyright (C) 2015-2018 IQIYI
 * All rights reserved.
 *
 * Author     : 王海斌
 * E-mail     : wanghaibin@qiyi.com
 * Version    :
*  Date       : Sun Apr 25 09:39:03 CST 2021
 * Destription: 测试打印函数调用堆栈
 *      注意：
 *          1. 编译时添加 -rdynamic 才能打印出来符号信息
 *          2. 需要使用O0进行编译，O1或O2或O3会导致优化输出堆栈不正确
 *          3. 静态函数调用在堆栈中不会输出
 */
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void print_trace(void) {
    int j, nptrs;
#define SIZE 100
    void* buffer[100];
    char** strings;

    nptrs = backtrace(buffer, SIZE);
    printf("backtrace() returned %d addresses\n", nptrs);

    strings = backtrace_symbols(buffer, nptrs);
    if (strings == NULL) {
        perror("backtrace_symbols");
        exit(EXIT_FAILURE);
    }

    for (j = 0; j < nptrs; j++) {
        printf("%s\n", strings[j]);
    }
    free(strings);
}

//void /* "static" means don't export the symbol... */
static void    myfunc2(void) {
    print_trace();
}

void myfunc(int ncalls) {
    if (ncalls > 1) {
        myfunc(ncalls - 1);
    } else {
        myfunc2();
    }
}

int main(int argc, char* argv[]) {
    if (argc != 2) {
        fprintf(stderr, "%s num-calls\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    myfunc(atoi(argv[1]));
    exit(EXIT_SUCCESS);
}
